#ifndef __APPCONFIG_H__
#define __APPCONFIG_H__

/***********************************************************
* @Date       : 2014-01-03
* @Description: 配置文件加载类
*		1、配置参数以行为单位
*		2、参数格式为：key = value
*       3、每一行最多支持255字节
*       4、以#开头的行表示注释
*       5、通过GETPARAM获取参数，参数为key、默认值， 默认值的类型即返回值的类型
*       6、支持类型const char*、std::string、int、double
*       示例：
		CAppConfig::LoadConfigFile("AppConfig.ini");
		int nPort = GETPARAM("Port", 21);
		std::string strUser = GETPARAM("User", "admin");
		double fee = GETPARAM("Fee", 1.23);
************************************************************/
#include <map>
#include <vector>
#include <string>

#include "singleton.h" 


#define  GETPARAM(group, param, defaultVal) CAppConfigAgent::get_instance().GetParam(group, param, defaultVal)

//参数转换类
template<typename T>
class ConvertParam
{
public:
	ConvertParam(const std::string& paramValue):m_paramValue(paramValue)
	{
	}
	T operator()()
	{
		return m_paramValue.c_str();
	}
public:
	const std::string& m_paramValue; 
};

//参数转换（特化）类
template<>
class ConvertParam<const char*>
{
public:
	ConvertParam(std::string& paramValue):m_paramValue(paramValue)
	{
	}
	const char* operator()()
	{
		return m_paramValue.c_str();
	}
public:
	std::string& m_paramValue; 
};

//参数转换（特化）类
template<>
class ConvertParam<int>
{
public:
	ConvertParam(const std::string& paramValue):m_paramValue(paramValue)
	{
	}
	int operator()()
	{
		return atoi(m_paramValue.c_str());
	}
public:
	const std::string& m_paramValue; 
};

//参数转换（特化）类
template<>
class ConvertParam<double>
{
public:
	ConvertParam(const std::string& paramValue):m_paramValue(paramValue)
	{
	}
	double operator()()
	{
		return atof(m_paramValue.c_str());
	}
public:
	const std::string& m_paramValue; 
};

class CAppConfig
{
public:
	bool	LoadConfigFile(const char* pszFileName);
	
	void AddConfigItem(const std::map<std::string, std::map<std::string, std::string>>& mapConfig);

	template<typename T>
    T GetParam(const char* pszGroup, const char* pszParam, T value)
	{
		if (m_paramList.find(pszGroup) == m_paramList.end())
		{
			return value;
		}
		if (m_paramList[pszGroup].find(pszParam) == m_paramList[pszGroup].end())
		{
			return value;
		}
		return ConvertParam<T>(m_paramList[pszGroup][pszParam])();
	}
	std::string Trim(const std::string& val);
	//根据前缀获取值列表
	std::vector<std::string> GetParamByPrefix(const char* pszGroup, const char* pszPrefix);
	std::vector<std::string> GetGroupVec();
	std::map<std::string, std::string>& GetGroupMap(const char* pszGroup);

private:
	typedef std::map<std::string, std::string> GROUPPARAM;

	std::map<std::string, GROUPPARAM> m_paramList;

};


typedef Singleton<CAppConfig> CAppConfigAgent;

#endif  //__APPCONFIG_H__
